package com.credithc.signature.callback.mq.retry;

import com.credithc.signature.callback.configure.rabbitmq.RabbitConfig;
import com.credithc.signature.callback.constant.DelayTypeEnum;
import com.credithc.signature.common.ro.callback.CallbackReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 描 述: <br/>
 * 作 者: Jingbo Hu<br/>
 * 创 建：2019年09⽉02⽇<br/>
 * 版 本：v1.0.0<br>
 * <p>
 * 历 史: (版本) 作者 时间 注释 <br/>
 */
@Component
@Slf4j
public class RetryProvider {

    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

    @Autowired
    private AmqpTemplate rabbitTemplate;

    /**
     * 发送延迟消息
     *
     * @param exchange
     * @param routerKey
     * @param callbackReq
     * @param delayTimes
     */
    public void sendMessage(String exchange, String routerKey, CallbackReq callbackReq, final long delayTimes) {
        try {
            // 执行发送消息到指定队列
            rabbitTemplate.convertAndSend(exchange, routerKey, callbackReq, message -> {
                // 设置延迟毫秒值
                message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
            });
            log.info("放入延迟队列成功...... requestSN=" + callbackReq.getRequestSN());
        } catch (Exception e) {
            log.error("放入延迟队列失败...... requestSN=" + callbackReq.getRequestSN(), e);
        }
    }

    /**
     * 发生延时消息
     *
     * @param callbackReq
     */
    public void sendDelayMsg(CallbackReq callbackReq) {
        // 1、重试超过5次，取消重试
        if (callbackReq.getRetryTime() > 5) {
            return;
        }

        // 2、获取延时时间
        DelayTypeEnum delayTypeEnum = DelayTypeEnum.getDelayTypeEnumByType(callbackReq.getRetryTime());
        int delayValue = delayTypeEnum.getDelayValue();
        String putTime = formatter.format(LocalDateTime.now());
        callbackReq.setPutTime(putTime);

        try {
            // 3、发送重试消息
            rabbitTemplate.convertAndSend(RabbitConfig.DELAY_EXCHANGE_NAME, RabbitConfig.DELAY_ROUTING_KEY, callbackReq, a -> {
                a.getMessageProperties().setDelay(delayValue);
                return a;
            });
            log.info("放入延迟队列成功...... requestSN=" + callbackReq.getRequestSN());
        } catch (Exception e) {
            log.error("放入延迟队列失败...... requestSN=" + callbackReq.getRequestSN(), e);
        }
    }
}
